#ifndef __NODE_2D_H__
#define __NODE_2D_H__

#include <iostream>
#include <vector>
#include <memory> 
#include <cmath>
using namespace std;

class GridNode;
using GridNodePtr = std::shared_ptr<GridNode>;

class GridNode{
    
    public:
        GridNode(): GridNode(0, 0, 0, 0){};
        GridNode(int x, int y, double g, double h) {
            this->x = x;
            this->y = y;
            this->g = g;
            this->h = h;
            this->pred = nullptr;
            this->idx = -1;
        }  

        int getX() const { return x; }
        int getY() const { return y; }
        int getIdx() const { return idx; }
        double getG() const { return g; }
        double getH() const { return h; }
        double getF() const { return g + h; }
        GridNodePtr getPred() const { return pred; }
        void getDir(int& dir_x, int& dir_y){
            dir_x = this->dir_x;
            dir_y = this->dir_y;
        }

        void setX(int x) { this->x = x; }
        void setY(int y) { this->y = y; }
        int setIdx(int width) { 
            this->idx = this->y * width + this->x; 
            return idx; 
        }
        void setG(double g) { this->g = g; }
        void setH(double h) { this->h = h; }
        void setPred(GridNodePtr pred) { this->pred = pred; }
        void setDir(int dir_x, int dir_y){
            this->dir_x = dir_x;
            this->dir_y = dir_y;
        }

        // 启发函数
        double movementCost(const GridNode& pred) const;
        void updateG() { 
            this->g += movementCost(*pred) * 0.7; 
        }
        void updateH(const GridNode& goal) { 
            this->h = movementCost(goal); 
        }

        // 比较节点是否相同
        bool operator == (const GridNode& rhs) const;

        // 邻域
        static const int dir;
        static const int dx[];
        static const int dy[];


    private:
        int x, y, idx;
        double g, h, f;
        int dir_x = 0;
        int dir_y = 0;
        GridNodePtr pred;

};

#endif